package com.ctshk.rpc.season.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SeasonType;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.air.dto.app.AirProductDetailDTO;
import com.ctshk.rpc.hotel.dto.HotelListDTO;
import com.ctshk.rpc.hotel.dto.HotelProductInfoDTO;
import com.ctshk.rpc.hotel.dto.HotelStockDTO;
import com.ctshk.rpc.hotel.service.IHotelProductService;
import com.ctshk.rpc.hotel.service.IHotelService;
import com.ctshk.rpc.season.dto.PackageProductCostDTO;
import com.ctshk.rpc.season.dto.SeasonFixedHotelBedTypeDTO;
import com.ctshk.rpc.season.dto.SeasonFixedProductPackageHotelDTO;
import com.ctshk.rpc.season.entity.SeasonFixedProductPackageHotel;
import com.ctshk.rpc.season.mapper.SeasonFixedProductPackageHotelMapper;
import com.ctshk.rpc.season.req.SeasonFixedProductPackageHotelReq;
import com.ctshk.rpc.season.req.UpdatePackageProductReq;
import com.ctshk.rpc.season.service.ISeasonFixedProductPackageHotelService;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 套票-固定套票单项产品打包-酒店表 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-09
 */
@Slf4j
@DubboService
public class SeasonFixedProductPackageHotelServiceImpl extends ServiceImpl<SeasonFixedProductPackageHotelMapper, SeasonFixedProductPackageHotel> implements ISeasonFixedProductPackageHotelService {

    @Autowired
    private SeasonFixedProductPackageHotelMapper seasonFixedProductPackageHotelMapper;

    @DubboReference
    private IHotelProductService hotelProductService;

    @DubboReference
    private IHotelService hotelService;

    public PackageProductCostDTO getHotelProductPrice(Long productId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        PackageProductCostDTO costDto = new PackageProductCostDTO();
        try {
            log.info("调用酒店服务获取入参channelType:{},productId:{},departureDate:{},userId:{},arrDate:{}", channelType, productId, departDate, userId, arrDate);
            Result<HotelStockDTO> result = hotelProductService.findHotelSalePriceInfoHandle(channelType, productId, departDate, arrDate, 0, userId);
            log.info("调用酒店服务获取价值:{}", JSON.toJSONString(result));
            if (result.isSuccess() && null != result.getData()
                    && result.getData().getStock() != null
                    && result.getData().getStock() > 0) {
                costDto.setCostPrice(result.getData().getPrice());
                costDto.setStock(result.getData().getStock());
            }
        } catch (Exception e) {
            log.error("调用酒店服务获取价格发生异常", e);
        }
        return costDto;
    }

    /* @MethodName: 固定套票默认酒店的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/19 13:32
     **/
    @Override
    public BigDecimal getDefaultHotelPrice(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        BigDecimal bd = BigDecimal.ZERO;
        //获取默认的 酒店产品 没有
        SeasonFixedProductPackageHotel hotel = seasonFixedProductPackageHotelMapper.selectOne(
                new QueryWrapper<SeasonFixedProductPackageHotel>().lambda().
                        eq(SeasonFixedProductPackageHotel::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageHotel::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageHotel::getPackageId, packageId)
        );
        if (null != hotel) {
            bd = getHotelProductPrice(hotel.getProductId(), departDate, arrDate, userId, channelType).getCostPrice();
        }
        return bd;
    }

    @Override
    public List<SeasonFixedProductPackageHotelDTO> getHotelByPackageId(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        List<SeasonFixedProductPackageHotel> resultList = seasonFixedProductPackageHotelMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageHotel>().lambda().
                        eq(SeasonFixedProductPackageHotel::getPackageId, packageId)
        );
        return getHotelByHotel(resultList, departDate, arrDate, userId, channelType);
    }

    private List<SeasonFixedProductPackageHotelDTO> getHotelByHotel(List<SeasonFixedProductPackageHotel> resultList, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        Multimap<Long, SeasonFixedProductPackageHotelDTO> map = LinkedHashMultimap.<Long, SeasonFixedProductPackageHotelDTO>create();
        List<SeasonFixedProductPackageHotelDTO> resultDtoList = new ArrayList<>();

        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageHotel result : resultList) {
                SeasonFixedProductPackageHotelDTO resultDto = EntityUtil.copy(result, SeasonFixedProductPackageHotelDTO.class);
                resultDto.setCost(getHotelProductPrice(result.getProductId(), departDate, arrDate, userId, channelType).getCostPrice());
                map.put(result.getHotelProductId(), resultDto);
            }
        }
        for (Long key : map.keySet()) {
            SeasonFixedProductPackageHotelDTO hotelDTO = null;
            List<SeasonFixedHotelBedTypeDTO> bedTypeDTOs = new ArrayList<>();
            Collection<SeasonFixedProductPackageHotelDTO> CabinClassVos = map.get(key);

            for (SeasonFixedProductPackageHotelDTO value : CabinClassVos) {

                if (null == hotelDTO) {
                    hotelDTO = EntityUtil.copy(value, SeasonFixedProductPackageHotelDTO.class);
                }

                SeasonFixedHotelBedTypeDTO ccd = EntityUtil.copy(value, SeasonFixedHotelBedTypeDTO.class);

                //查询房型信息
                bedTypeDTOs.add(ccd);
            }
            bedTypeDTOs.sort(new Comparator<SeasonFixedHotelBedTypeDTO>() {
                @Override
                public int compare(SeasonFixedHotelBedTypeDTO o1, SeasonFixedHotelBedTypeDTO o2) {
                    return o2.getCost().compareTo(o1.getCost());
                }
            });

            if(null == hotelDTO.getHotelProductId()){
                log.info("酒店ID为空");
            }else{

                log.info("酒店产品ID为"+hotelDTO.getHotelProductId());

                HotelProductInfoDTO hotelProductInfoDTO = hotelProductService.selectById(hotelDTO.getProductId());

                if(hotelProductInfoDTO == null){
                    log.info("酒店产品未查询到！");
                }else{
                    HotelListDTO hotelListDTO = hotelService.queryDetail(hotelDTO.getHotelProductId());

                    if(hotelListDTO == null){
                        log.info("酒店资源信息查询失败！");
                    }else {
                        hotelDTO.setEnName(hotelListDTO.getEnName());
                        hotelDTO.setLocation(hotelListDTO.getLocation());
                        hotelDTO.setStarLevel(hotelListDTO.getStarLevel());

                        log.info("酒店英文名称："+hotelListDTO.getEnName());
                        log.info("酒店地址："+hotelListDTO.getLocation());
                        log.info("酒店星级："+hotelListDTO.getStarLevel());

                        if(hotelProductInfoDTO.getAllowRefund() != null
                                && hotelProductInfoDTO.getAllowRefund() == 1){
                            hotelDTO.setAllowRefund(true);
                        }else{
                            hotelDTO.setAllowRefund(false);
                        }
                    }


                }


            }

            hotelDTO.setBedTypeDTOs(bedTypeDTOs);
            resultDtoList.add(hotelDTO);
        }
        return resultDtoList;
    }

    @Override
    public List<SeasonFixedProductPackageHotelDTO> getDefaultHotelData(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        List<SeasonFixedProductPackageHotel> resultList = seasonFixedProductPackageHotelMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageHotel>().lambda().
                        eq(SeasonFixedProductPackageHotel::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageHotel::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageHotel::getPackageId, packageId)
        );
        List<SeasonFixedProductPackageHotelDTO> resultDtoList = new ArrayList<>();
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageHotel result : resultList) {
                SeasonFixedProductPackageHotelDTO resultDto = EntityUtil.copy(result, SeasonFixedProductPackageHotelDTO.class);
                resultDto.setCost(getHotelProductPrice(resultDto.getProductId(), departDate, arrDate, userId, channelType).getCostPrice());

                //TODO 补全酒店信息
                if(null == resultDto.getHotelProductId()){
                    log.info("酒店ID为空");
                }else{

                    log.info("酒店产品ID为"+resultDto.getHotelProductId());

                    HotelProductInfoDTO hotelProductInfoDTO = hotelProductService.selectById(resultDto.getProductId());

                    if(hotelProductInfoDTO == null){
                        log.info("酒店产品未查询到！");
                    }else{
                        HotelListDTO hotelListDTO = hotelService.queryDetail(resultDto.getHotelProductId());

                        if(hotelListDTO == null){
                            log.info("酒店资源信息查询失败！");
                        }else {
                            resultDto.setEnName(hotelListDTO.getEnName());
                            resultDto.setLocation(hotelListDTO.getLocation());
                            resultDto.setStarLevel(hotelListDTO.getStarLevel());

                            log.info("酒店英文名称："+hotelListDTO.getEnName());
                            log.info("酒店地址："+hotelListDTO.getLocation());
                            log.info("酒店星级："+hotelListDTO.getStarLevel());
//                            log.info("酒店星级："+hotelListDTO.getc());

                            if(hotelProductInfoDTO.getAllowRefund() != null
                                    && hotelProductInfoDTO.getAllowRefund() == 1){
                                resultDto.setAllowRefund(true);
                            }else{
                                resultDto.setAllowRefund(false);
                            }
                        }


                    }


                }

                resultDtoList.add(resultDto);
            }
        }
        return resultDtoList;
    }

    /* @MethodName: 批量保存酒店产品 信息
     * @Description: TODO
     * @Param: userId 用户id  productId产品id packageId 打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/9 18:18
     **/
    @Override
    public void batchHotelProduct(Long userId, Long packageId, List<SeasonFixedProductPackageHotelReq> hotelReqList) {
        LocalDateTime now = LocalDateTime.now();
        List<SeasonFixedProductPackageHotel> busList = hotelReqList.stream().map(
                hoteReq -> {
                    SeasonFixedProductPackageHotel hote = EntityUtil.copy(hoteReq, SeasonFixedProductPackageHotel.class);
                    hote.setCreateId(userId);
                    hote.setPackageId(packageId);
                    hote.setGmtCreate(now);
                    hote.setId(IdWorker.getId());
                    hote.setIsDeleted(IsDeletedCode.NO.getCode());
                    return hote;
                }
        ).collect(Collectors.toList());

        seasonFixedProductPackageHotelMapper.insertBatchSomeColumn(busList);
    }

    /* @MethodName: 获取固定套票 酒店产品信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 13:32
     **/
    @Override
    public List<SeasonFixedProductPackageHotelDTO> getSeasonFixedProductHotelDtoList(Long packageId) {
        List<SeasonFixedProductPackageHotel> productPackageHotelList = getAllSeasonFixedProductHotelList(packageId);
        List<SeasonFixedProductPackageHotelDTO> list = new LinkedList<>();
        if (null != productPackageHotelList && productPackageHotelList.size() > 0) {
            list = productPackageHotelList.stream().map(
                    hotel -> {
                        SeasonFixedProductPackageHotelDTO hotelDto = EntityUtil.copy(hotel, SeasonFixedProductPackageHotelDTO.class);
                        return hotelDto;
                    }
            ).collect(Collectors.toList());
        }
        return list;
    }

    /* @MethodName: 获取固定产品 酒店产品 信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 11:40
     **/
    @Override
    public void deletePreviousHotel(Long userId, Long packageId) {
        LocalDateTime now = LocalDateTime.now();
        UpdateWrapper<SeasonFixedProductPackageHotel> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("modified_id", userId);//修改人
        updateWrapper.set("is_deleted", IsDeletedCode.YES.getCode());//删除
        updateWrapper.set("gmt_modified", now);//修改时间
        updateWrapper.eq("package_id", packageId);
        seasonFixedProductPackageHotelMapper.update(null, updateWrapper);
    }


    /* @MethodName: 获取 酒店成本 差价信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 10:54
     **/
    @Override
    public List<SeasonFixedProductPackageHotelDTO> getHotelDifferencePrice(UpdatePackageProductReq req) {
        Long packageId = req.getPackageId();

        LocalDate queryDate = req.getStartDate();
        Integer roomNum = req.getRoomNum();//房间数
        Integer travelNight = req.getTravelNights();//行程 晚数
        List<SeasonFixedProductPackageHotelDTO> list = new LinkedList<>();
        SeasonFixedProductPackageHotelDTO hotelDTO = getSeasonFixedDefaultProductHotel(packageId, queryDate, req.getUserId(), roomNum, travelNight);
        list.add(hotelDTO);
        BigDecimal flagCost = hotelDTO.getCost();
        List<SeasonFixedProductPackageHotel> hotelList = getSeasonFixedProductHotelList(packageId);
        hotelList.stream().forEach(
                hotel -> {
                    Long hotelProductId = hotel.getProductId();
                    SeasonFixedProductPackageHotelDTO hotelDto = EntityUtil.copy(hotel, SeasonFixedProductPackageHotelDTO.class);
                    BigDecimal hotelCost = BigDecimal.ZERO;
                    BigDecimal singleRoomCost = BigDecimal.ZERO;
                    hotelDto.setCost(hotelCost);
                    if (hotelCost.compareTo(BigDecimal.ZERO) == 0) {//表示没有库存
                        hotelDto.setPriceDifference("售罄");
                    } else {
                        hotelDto.setPriceDifference(String.valueOf(flagCost.subtract(hotelCost)));//减法
                    }
                    hotelDTO.setSingleRoomCost(singleRoomCost);//单间单晚成本
                    list.add(hotelDto);
                });


        return list;
    }


    /* @MethodName: 获取 不是默认 的酒店产品信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 10:20
     **/
    private List<SeasonFixedProductPackageHotel> getSeasonFixedProductHotelList(Long packageId) {
        List<SeasonFixedProductPackageHotel> list = seasonFixedProductPackageHotelMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageHotel>().lambda()
                        .eq(SeasonFixedProductPackageHotel::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageHotel::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageHotel::getIsDefault, SeasonType.NO_DEFAULT.getCode())
        );
        return list;

    }

    /* @MethodName: 获取默认的 酒店票信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 10:32
     **/
    public SeasonFixedProductPackageHotelDTO getSeasonFixedDefaultProductHotel(Long packageId, LocalDate queryDate, Long userId, int roomNum, int travelNight) {
        SeasonFixedProductPackageHotel hotel = seasonFixedProductPackageHotelMapper.selectOne(
                new QueryWrapper<SeasonFixedProductPackageHotel>().lambda()
                        .eq(SeasonFixedProductPackageHotel::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageHotel::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageHotel::getIsDefault, SeasonType.YES_DEFAULT.getCode())
        );

        SeasonFixedProductPackageHotelDTO hotelDTO = EntityUtil.copy(hotel, SeasonFixedProductPackageHotelDTO.class);
        BigDecimal hotelCost = BigDecimal.ZERO;
        hotelDTO.setCost(hotelCost);
        if (hotelCost.compareTo(BigDecimal.ZERO) == 0) {
            hotelDTO.setPriceDifference("售罄");
        } else {
            hotelDTO.setPriceDifference("0");
        }
        return hotelDTO;
    }


    /* @MethodName: 获取固定套票 酒店产品信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 13:32
     **/
    private List<SeasonFixedProductPackageHotel> getAllSeasonFixedProductHotelList(Long packageId) {
        QueryWrapper<SeasonFixedProductPackageHotel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("package_id", packageId);
        queryWrapper.eq("is_deleted", IsDeletedCode.NO.getCode());
        return seasonFixedProductPackageHotelMapper.selectList(queryWrapper);
    }
}
